"""
流程引擎相关数据模型
"""
import json
from datetime import datetime
from typing import Dict, List, Optional, Any, Union

class ProcessDefinition:
    """流程定义数据模型"""
    
    def __init__(self, id: str, key: str, name: str, version: int, deployment_id: str, 
                resource_name: str, description: Optional[str] = None, version_tag: Optional[str] = None, 
                tenant_id: Optional[str] = None, metadata: Optional[Dict] = None):
        """初始化流程定义
        
        Args:
            id: 流程定义ID
            key: 流程定义唯一键
            name: 流程名称
            version: 流程版本号
            deployment_id: 部署ID
            resource_name: 资源文件名
            description: 流程描述
            version_tag: 版本标签
            tenant_id: 租户ID
            metadata: 元数据
        """
        self.id = id
        self.key = key
        self.name = name
        self.version = version
        self.deployment_id = deployment_id
        self.resource_name = resource_name
        self.description = description
        self.version_tag = version_tag
        self.tenant_id = tenant_id
        self.metadata = metadata or {}
        self.created_at = datetime.now()
    
    @classmethod
    def from_camunda_response(cls, data: Dict) -> 'ProcessDefinition':
        """从Camunda API响应创建流程定义对象
        
        Args:
            data: Camunda API响应数据
            
        Returns:
            流程定义对象
        """
        return cls(
            id=data.get('id'),
            key=data.get('key'),
            name=data.get('name'),
            version=data.get('version'),
            deployment_id=data.get('deploymentId'),
            resource_name=data.get('resource'),
            description=data.get('description'),
            version_tag=data.get('versionTag'),
            tenant_id=data.get('tenantId'),
            metadata={
                'suspended': data.get('suspended', False),
                'startable_in_tasklist': data.get('startableInTasklist', True),
                'category': data.get('category')
            }
        )
    
    def to_dict(self) -> Dict:
        """转换为字典
        
        Returns:
            字典表示
        """
        return {
            'id': self.id,
            'key': self.key,
            'name': self.name,
            'version': self.version,
            'deployment_id': self.deployment_id,
            'resource_name': self.resource_name,
            'description': self.description,
            'version_tag': self.version_tag,
            'tenant_id': self.tenant_id,
            'metadata': self.metadata,
            'created_at': self.created_at.isoformat()
        }


class ProcessInstance:
    """流程实例数据模型"""
    
    def __init__(self, id: str, definition_id: str, business_key: Optional[str] = None, 
                tenant_id: Optional[str] = None, variables: Optional[Dict] = None, 
                parent_id: Optional[str] = None, status: str = 'ACTIVE'):
        """初始化流程实例
        
        Args:
            id: 流程实例ID
            definition_id: 流程定义ID
            business_key: 业务键
            tenant_id: 租户ID
            variables: 流程变量
            parent_id: 父流程实例ID
            status: 状态 (ACTIVE, SUSPENDED, COMPLETED, TERMINATED)
        """
        self.id = id
        self.definition_id = definition_id
        self.business_key = business_key
        self.tenant_id = tenant_id
        self.variables = variables or {}
        self.parent_id = parent_id
        self.status = status
        self.created_at = datetime.now()
        self.updated_at = datetime.now()
    
    @classmethod
    def from_camunda_response(cls, data: Dict) -> 'ProcessInstance':
        """从Camunda API响应创建流程实例对象
        
        Args:
            data: Camunda API响应数据
            
        Returns:
            流程实例对象
        """
        return cls(
            id=data.get('id'),
            definition_id=data.get('definitionId'),
            business_key=data.get('businessKey'),
            tenant_id=data.get('tenantId'),
            parent_id=data.get('parentId'),
            status='SUSPENDED' if data.get('suspended', False) else 'ACTIVE'
        )
    
    def to_dict(self) -> Dict:
        """转换为字典
        
        Returns:
            字典表示
        """
        return {
            'id': self.id,
            'definition_id': self.definition_id,
            'business_key': self.business_key,
            'tenant_id': self.tenant_id,
            'variables': self.variables,
            'parent_id': self.parent_id,
            'status': self.status,
            'created_at': self.created_at.isoformat(),
            'updated_at': self.updated_at.isoformat()
        }
    
    def update_variables(self, variables: Dict):
        """更新流程变量
        
        Args:
            variables: 要更新的变量
        """
        self.variables.update(variables)
        self.updated_at = datetime.now()


class Task:
    """任务数据模型"""
    
    def __init__(self, id: str, name: str, process_instance_id: str, 
                process_definition_id: str, task_definition_key: str, 
                assignee: Optional[str] = None, created: Optional[datetime] = None,
                due_date: Optional[datetime] = None, follow_up_date: Optional[datetime] = None,
                form_key: Optional[str] = None, tenant_id: Optional[str] = None):
        """初始化任务
        
        Args:
            id: 任务ID
            name: 任务名称
            process_instance_id: 流程实例ID
            process_definition_id: 流程定义ID
            task_definition_key: 任务定义键
            assignee: 分配人
            created: 创建时间
            due_date: 截止日期
            follow_up_date: 跟进日期
            form_key: 表单键
            tenant_id: 租户ID
        """
        self.id = id
        self.name = name
        self.process_instance_id = process_instance_id
        self.process_definition_id = process_definition_id
        self.task_definition_key = task_definition_key
        self.assignee = assignee
        self.created = created or datetime.now()
        self.due_date = due_date
        self.follow_up_date = follow_up_date
        self.form_key = form_key
        self.tenant_id = tenant_id
        self.variables = {}
    
    @classmethod
    def from_camunda_response(cls, data: Dict) -> 'Task':
        """从Camunda API响应创建任务对象
        
        Args:
            data: Camunda API响应数据
            
        Returns:
            任务对象
        """
        # 解析日期字段
        created = None
        if data.get('created'):
            try:
                created = datetime.fromisoformat(data.get('created').replace('Z', '+00:00'))
            except (ValueError, TypeError):
                pass
        
        due_date = None
        if data.get('due'):
            try:
                due_date = datetime.fromisoformat(data.get('due').replace('Z', '+00:00'))
            except (ValueError, TypeError):
                pass
        
        follow_up_date = None
        if data.get('followUp'):
            try:
                follow_up_date = datetime.fromisoformat(data.get('followUp').replace('Z', '+00:00'))
            except (ValueError, TypeError):
                pass
        
        return cls(
            id=data.get('id'),
            name=data.get('name'),
            process_instance_id=data.get('processInstanceId'),
            process_definition_id=data.get('processDefinitionId'),
            task_definition_key=data.get('taskDefinitionKey'),
            assignee=data.get('assignee'),
            created=created,
            due_date=due_date,
            follow_up_date=follow_up_date,
            form_key=data.get('formKey'),
            tenant_id=data.get('tenantId')
        )
    
    def to_dict(self) -> Dict:
        """转换为字典
        
        Returns:
            字典表示
        """
        return {
            'id': self.id,
            'name': self.name,
            'process_instance_id': self.process_instance_id,
            'process_definition_id': self.process_definition_id,
            'task_definition_key': self.task_definition_key,
            'assignee': self.assignee,
            'created': self.created.isoformat() if self.created else None,
            'due_date': self.due_date.isoformat() if self.due_date else None,
            'follow_up_date': self.follow_up_date.isoformat() if self.follow_up_date else None,
            'form_key': self.form_key,
            'tenant_id': self.tenant_id,
            'variables': self.variables
        } 